To provide desired high availability and serviceability features, embedded systems are increasingly using micro kernels. In this environment, every process has its own memory space and can access its own address space only. Any attempt to access outside its own address space will kill the process.
In this micro kernel environment, communication between two processes is achieved by Inter Process Communication (IPC). Typically a micro kernel provides more then one method for IPC and selection of a particular method depends on the degree of fault isolation required, the amount and frequency of data that needs to be communicated, and the overall performance required. For processes that are very performance sensitive and have large amount of data to share, IPC using shared memory is often preferred.
Multiple related processes running on the system can interact with each other. For sharing data between these different processes, the operating system (OS) provides several facilities. A typical POSIX (a portable operating system based on UNIX) operating system provides following IPC facilities:
Shared memory
Message queue
Semaphores
Named Pipes etc.
Shared Memory is the most efficient method for sharing and/or exchanging large amount of data. Large data structures can be shared using shared memory.
For a process to access shared memory, the shared memory must be mapped into the processes address space. This is typically done by a memory management call (mmap) provided by the kernel. An “mmap” system call maps the specified memory in the address space of calling process.
Multiple processes accessing the shared memory can be treated as peers, where every process has equal rights to read, write, extend and shrink the shared memory.
Alternatively, multiple processes accessing the shared memory can also work in the client server/mode, where one process (server) typically has more rights than the client. Typically in this mode, the server process has rights to read, write, extend, and shrink the memory, while client processes can only read and write the memory.
However, using shared memory becomes very complicated if shared data is not flat, i.e., includes pointers linking data structures, or is not contiguous. Typically processes will use pools of memory. When one pool runs out a process will allocate the next shared memory pool and link the pools together. Problems also arise from the fact that pointers to some part of this shared memory may be stored into other data structures that are stored in this memory (linked lists, etc.). If the shared memory is not mapped immediately into all the processes that are using it, then processes that do not have the additional memory mapped will crash.
For these types of shared data patterns, all processes accessing the shared memory must map the shared memory into their address space before the data structure can be modified and used. In cases where non-contiguous memory is allocated, this memory must be mapped into address spaces of all the processes that are using it before memory becomes useful.
This means that every process must implement a protocol to map and access this shared memory. These protocols make the entire system complicated and inefficient.
Further, these protocols typically require the application that is changing the size of shared memory to send a notification to all the users of memory and to wait for confirmation from them. While this is going on, memory may be locked down and unusable by other processes.